<?php
$s_host = '0.0.0.0';
$i_port = 6666;
$r_listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($r_listen_socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_option($r_listen_socket, SOL_SOCKET, SO_REUSEPORT, 1);
socket_bind($r_listen_socket, $s_host, $i_port);
socket_listen($r_listen_socket);
// 将$listen_socket设置为非阻塞IO
socket_set_nonblock($r_listen_socket);
// 这两个数组级别的变量非常有意思
// 一个用于保存event对象
// 一个用于保存client的连接socket
$a_event_array = array();
$a_client_array = array();
// 创建event-base
$o_event_base = new EventBase();
$s_method_name = $o_event_base->getMethod();
// 确保自己用的是epoll
if ('epoll' != $s_method_name) {
    exit("not epoll");
}
// 在$listen_socket上添加一个 持久的读事件
// 为啥是读事件？
// 因为$listen_socket上发生事件就是：客户端建立连接
// 所以，应该是读事件
// 而且，我们应该用上 PERSIST 将事件设置为持久事件

$o_event = new Event($o_event_base, $r_listen_socket, Event::READ | Event::PERSIST,

    function ($r_listen_socket, $i_event_flag, $o_event_base) {
        global $a_event_array;
        global $a_client_array;
        // socket_accept接受连接，生成一个新的socket，一个客户端连接socket
        $r_connection_socket = socket_accept($r_listen_socket);
        echo "new Connnect ".intval($r_connection_socket).PHP_EOL;
        // 注意这个操作：将客户端连接保存到数组...
        // 如果没有这行，客户端连接上后自动断开...
        $a_client_array[intval($r_connection_socket)] = $r_connection_socket;
        // 在这个客户端连接socket上添加 持久的读事件
        // 也就说 要从客户端连接上读取消息
        $o_event = new Event($o_event_base, $r_connection_socket, Event::READ | Event::PERSIST,
            function ($r_connection_socket,$o_event)
            {
                global $a_event_array;
                global $a_client_array;
                $s_content = socket_read($r_connection_socket, 1024);
                if(empty($s_content)){
                    $index_client=array_search($r_connection_socket,$a_client_array);
                    unset($a_client_array[$index_client]); //链接一定要清除
                    unset($a_event_array[$index_client]);

                    echo intval($r_connection_socket)." lost".PHP_EOL;


                }else{
                    echo "msg from ".intval($r_connection_socket).":".$s_content;
                }

        });


        $o_event->add();
        // 注意这个操作：将事件保存到事件数组...
        // 如果没有这行，那么事件会丢失，客户端发送的消息毛都收不到
        $a_event_array[intval($r_connection_socket)] = $o_event;
    }, $o_event_base);

$o_event->add();
// 注意这个操作：将事件保存到事件数组...
//$a_event_array[] = $o_event;
// loop起来...
$o_event_base->loop();